﻿using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SmallBusinessKit.DataAccess.Repositories;
using SmallBusinessKit.Models.Entities;

namespace SmallBusinessKit.Tests.Repositories
{
    /// <summary>
    /// Unit Tests for XmlCategoryRepository Logic
    /// </summary>
    [TestClass]
    public class XmlCategoryRepositoryTests : UnitTestBase
    {
        #region Properties

        private XmlCategoryRepository _xmlRep;

        #endregion Properties

        #region Tests

        [TestInitialize]
        public override void Setup()
        {
            base.Setup();

            var categories = XmlData.ParseCategories();      // use data from file to save time...
            categories.ElementAt(2).IsVisible = false;       // to test GetMany(i => i.IsVisible)
            categories.ElementAt(4).IsVisible = false;       // to test GetMany(i => i.IsVisible)

            _xmlRep = new XmlCategoryRepository(categories);
        }

        [TestMethod]
        public void XmlCategoryGetById()
        {
            // Act
            var result = _xmlRep.GetById("c11");

            // Assert
            Assert.IsNotNull(result);
            Assert.IsInstanceOfType(result, typeof(Category));
            Assert.AreEqual("c11", result.Id);
        }

        [TestMethod]
        public void XmlCategoryGet()
        {
            // Act
            var result = _xmlRep.Get(i => i.Id == "c13");

            // Assert
            Assert.IsNotNull(result);
            Assert.IsInstanceOfType(result, typeof(Category));
            Assert.AreEqual("c13", result.Id);
        }

        [TestMethod]
        public void XmlCategoryGetMany()
        {
            // Act
            var results = _xmlRep.GetMany(i => i.IsVisible).ToList();

            // Assert
            Assert.IsNotNull(results);
            Assert.IsInstanceOfType(results, typeof (IEnumerable<Category>));
            Assert.AreEqual(14, results.Count());
        }

        [TestMethod]
        public void XmlCategoryGetManyWithItemsOnly()
        {
            // Act
            var results = _xmlRep.GetMany(i => i.Items.Any()).ToList();

            // Assert
            Assert.IsNotNull(results);
            Assert.IsInstanceOfType(results, typeof(IEnumerable<Category>));
            Assert.AreEqual(8, results.Count());
        }

        [TestMethod]
        public void XmlCategoryGetManyTopLevel()
        {
            // Act
            var results = _xmlRep.GetMany(i => i.ParentId == null).ToList();

            // Assert
            Assert.IsNotNull(results);
            Assert.IsInstanceOfType(results, typeof(IEnumerable<Category>));
            Assert.AreEqual(5, results.Count());
        }

        [TestMethod]
        public void XmlCategoryGetAll()
        {
            // Act
            var results = _xmlRep.GetAll().ToList();

            // Assert
            Assert.IsNotNull(results);
            Assert.IsInstanceOfType(results, typeof(IEnumerable<Category>));
            Assert.AreEqual(16, results.Count());
        }

        [TestMethod]
        public void XmlCategoryHasItems()
        {
            // Act
            var result = _xmlRep.Get(i => i.Id == "c11");

            // Assert
            Assert.IsNotNull(result);
            Assert.IsInstanceOfType(result, typeof(Category));
            Assert.IsInstanceOfType(result.Items, typeof(IEnumerable<Item>));
            Assert.AreEqual(3, result.Items.Count);
        }
        
        [TestMethod]
        public void XmlCategoryHasParent()
        {
            // Act
            var result = _xmlRep.Get(i => i.Id == "c11");

            // Assert
            Assert.IsNotNull(result);
            Assert.IsNotNull(result.Parent);
            Assert.IsInstanceOfType(result, typeof(Category));
            Assert.IsInstanceOfType(result.Parent, typeof(Category));
            Assert.AreEqual("c01", result.Parent.Id);
        }

        #endregion
    }
}
